package IO;

import org.junit.Test;

import java.io.*;

/**
 * 一、流的分类
 *      1.操作数据的单位：【字节流】、【字符流】
 *      2.数据的流向：输入流、输出流
 *      3.流的角色：节点流、处理流
 * 二、流的体系结构
 * 抽象基类     InputStream          OutputStream           Reader            Writer
 * 节点流(文件流)FileInputStream      FileOutputStream       FileReader        FileWriter
 * 缓冲流(处理流)BufferedInputStream  BufferedOutputStream   BufferedReader    BufferedWriter
 * 转换流(in字节输入流转为字符输入流、out字节输出流转为字符输出流)  InputStreamReader OutputStreamWriter
 * 打印流                            PrintStream                              PrintWriter
 * 数据流      DataInputStream       DataOutputStream
 * 对象流  ObjectInputStream(反序列化)ObjectOutputStream(序列化)
 * 对象的序列化机制：允许将【内存】中的对象转换为与平台无关的二进制流,是JavaEE平台的基础
 *           好处：对象转为字节数据,持久的保存在【磁盘】中,随需求读取
 *   可序列化的需求：实现Serializable接口(标识接口)或者Externalizable接口
 *                 实现一个表示序列化版本标识符的静态常量UID,进行【版本控制】,检查兼容性
 *        注意事项：1.UID不写时系统根据内部细节自动生成的,当版本更新后又会重新生成新的序列号,
 *                 产生类型转换异常(InvalidCastException),故建议显示声明
 *                 2.默认对象所有属性都是可序列化的(包括基本类型数据),
 *                 对象流不能序列化static好transient修饰的成员变量
 * 随机存取流RandomAccessFile:1.声明在io包下,但是直接继承于Object并实现输入输出方法,意味着其既可以读也可以写
 *                          2.支持“随机访问”方式(文件记录指针),可以通过seek跳到文件任意位置读写(覆盖写入)
 *                          3.实例化参数 r:只读/rw:读写/rwd:读写同步内容更新/rwds:读写同步内容好元数据更新
 *                          4.文件不存在会自动创建文件,文件存在内容时会默认从头开始覆盖
 * 字节数组输出流ByteArrayOutputStream:1.数据被写入一个 byte[]数组,初始长度32,每次扩容为2倍
 *                                  2.缓冲区会随着数据的不断写入而自动增长
 *                                  3.可使用toByteArray()和toString()获取数据
 */
public class FileReaderWriterDemo {
    //一、读取流
    @Test
    public void test(){
        FileReader fileReader=null;
        try {
            //1.实例化File对象
            File file = new File("user.dat");
            //2.提供具体的流
            fileReader = new FileReader(file);
            //3.数据的读取,返回一个字符，文件末尾返回-1
            int data;//单字节读取
            while ((data=fileReader.read())!=-1){
                System.out.print((char) data);
            }
            char[] line =new char[1024];//字符块读取
            while ((data=fileReader.read(line))!=-1){
                
                String s = new String(line, 0, data);
                System.out.println(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4.资源的关闭
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //二、输出流
    @Test
    public void test1(){
        //输出流实例化，文件存在则写入，文件不存在则自动创建
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(new File("user.dat"),true);
            
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //三、写入和输出同时使用字符流读取文本文件，无法用char[]读取图片
    @Test
    public void test2(){
        //输出流实例化，文件存在则写入，文件不存在则自动创建
        FileReader fileReader=null;
        FileWriter fileWriter = null;
        try {
            fileReader = new FileReader(new File("user.dat"));
            fileWriter = new FileWriter(new File("user1.dat"),true);
        int data;
        char[] line=new char[1024];
        while ((data=fileReader.read(line))!=-1){
            fileWriter.write(line,0,data);
        }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fileReader.close();
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
